const fp = require('lodash/fp');

class Container {
    static of(value) {
        return new Container(value);
    }
    constructor(value) {
        this._value = value
    }
    map(fn) {
        return Container.of(fn(this._value))
    }
}
class Maybe {
    static of(x) {
        return new Maybe(x)
    }
    isNothing() {
        return this._value === null || this._value === undefined
    }
    constructor(x) {
        this._value = x
    }
    map(fn) {
        return this.isNothing() ? this : Maybe.of(fn(this._value))
    }
}

// 题_________________-：

// 3.1
let maybe = Maybe.of([5, 6, 1])
    // 答
let ex1 = (co, addVal) => {
    if (!co._value instanceof Array) return;
    return co.map(array => fp.map(item => fp.add(item, addVal), array))
}
console.log('ex1==>', ex1(maybe, 2));

// 3.2
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do'])
    // 答
let ex2 = (co) => {
    return co.map(array => fp.first(array))._value;
}
console.log('ex2==>', ex2(xs));


// 3.3
let safeProp = fp.curry(function(x, o) {
    return Maybe.of(o[x])
})
let user = {
        id: 2,
        name: 'Albert'
    }
    // 答
let ex3 = (obj, attr) => {
    return safeProp(attr, obj).map(value => fp.first(value))._value;
}
console.log('ex3==>', ex3(user, 'name'));


// 3.4
let ex4Source = function(n) {
        if (n) {
            return parseInt(n)
        }
    }
    // 答
let ex4 = n => {
    let co = Maybe.of(n).map(item => item && parseInt(item)),
        value = co._value;
    return (!co.isNothing() && value.toString()) == 'NaN' ? NaN : (value || undefined)
};
console.log(ex4Source('sadf'));
console.log(ex4('sadf'));